<?php

class Loader {

	/**
	 * 类名映射信息
	 * @var array
	 */
	protected static $classMap = [];

	/**
	 * 类库别名
	 * @var array
	 */
	protected static $classAlias = [];

	/**
	 * PSR-4
	 * @var array
	 */
	private static $prefixLengthsPsr4 = [];
	private static $prefixDirsPsr4    = [];
	private static $fallbackDirsPsr4  = [];

	/**
	 * PSR-0
	 * @var array
	 */
	private static $prefixesPsr0     = [];
	private static $fallbackDirsPsr0 = [];

	/**
	 * 需要加载的文件
	 * @var array
	 */
	private static $files = [];

	/**
	 * Composer安装路径
	 * @var string
	 */
	private static $composerPath;

	// 获取应用根目录
	public static function getRootPath()
	{
		if ('cli' == PHP_SAPI) {
			$scriptName = realpath($_SERVER['argv'][0]);
		} else {
			$scriptName = $_SERVER['SCRIPT_FILENAME'];
		}

		$path = realpath(dirname($scriptName));

		if (!is_file($path . DIRECTORY_SEPARATOR . 'think')) {
			$path = dirname($path);
		}

		return $path . DIRECTORY_SEPARATOR;
	}

	// 自动载入
	public static function register()
	{
		spl_autoload_register(function ($className) {
			$className = "../" . str_replace("/", "\\", $className) . ".php";
			if (is_file($className)) {
				require $className;
			} else {
				echo $className . "自动载入失败";
			}
		});

		$rootPath = self::getRootPath();

		require_once $rootPath . '/vendor/autoload.php';

//		self::$composerPath = $rootPath . 'vendor' . DIRECTORY_SEPARATOR . 'composer' . DIRECTORY_SEPARATOR;
//
//		// Composer自动加载支持
//		if (is_dir(self::$composerPath)) {
//			if (is_file(self::$composerPath . 'autoload_static.php')) {
//				require self::$composerPath . 'autoload_static.php';
//				$declaredClass = get_declared_classes();
//				$composerClass = array_pop($declaredClass);
//				foreach (['prefixLengthsPsr4', 'prefixDirsPsr4', 'fallbackDirsPsr4', 'prefixesPsr0', 'fallbackDirsPsr0', 'classMap', 'files'] as $attr) {
//					if (property_exists($composerClass, $attr)) {
//						self::${$attr} = $composerClass::${$attr};
//					}
//				}
//			} else {
//				self::registerComposerLoader(self::$composerPath);
//			}
//		}
//		// 注册命名空间定义
//		self::addNamespace([
//			'think'  => __DIR__
//		]);
	}

	// 注册composer自动加载
	public static function registerComposerLoader($composerPath)
	{
		if (is_file($composerPath . 'autoload_namespaces.php')) {
			$map = require $composerPath . 'autoload_namespaces.php';
			foreach ($map as $namespace => $path) {
				self::addPsr0($namespace, $path);
			}
		}

		if (is_file($composerPath . 'autoload_psr4.php')) {
			$map = require $composerPath . 'autoload_psr4.php';
			foreach ($map as $namespace => $path) {
				self::addPsr4($namespace, $path);
			}
		}

		if (is_file($composerPath . 'autoload_classmap.php')) {
			$classMap = require $composerPath . 'autoload_classmap.php';
			if ($classMap) {
				self::addClassMap($classMap);
			}
		}

		if (is_file($composerPath . 'autoload_files.php')) {
			self::$files = require $composerPath . 'autoload_files.php';
		}
	}

	// 注册命名空间
	public static function addNamespace($namespace, $path = '')
	{
		if (is_array($namespace)) {
			foreach ($namespace as $prefix => $paths) {
				self::addPsr4($prefix . '\\', rtrim($paths, DIRECTORY_SEPARATOR), true);
			}
		} else {
			self::addPsr4($namespace . '\\', rtrim($path, DIRECTORY_SEPARATOR), true);
		}
	}

	// 添加Ps0空间
	private static function addPsr0($prefix, $paths, $prepend = false)
	{
		if (!$prefix) {
			if ($prepend) {
				self::$fallbackDirsPsr0 = array_merge(
					(array) $paths,
					self::$fallbackDirsPsr0
				);
			} else {
				self::$fallbackDirsPsr0 = array_merge(
					self::$fallbackDirsPsr0,
					(array) $paths
				);
			}

			return;
		}

		$first = $prefix[0];
		if (!isset(self::$prefixesPsr0[$first][$prefix])) {
			self::$prefixesPsr0[$first][$prefix] = (array) $paths;

			return;
		}

		if ($prepend) {
			self::$prefixesPsr0[$first][$prefix] = array_merge(
				(array) $paths,
				self::$prefixesPsr0[$first][$prefix]
			);
		} else {
			self::$prefixesPsr0[$first][$prefix] = array_merge(
				self::$prefixesPsr0[$first][$prefix],
				(array) $paths
			);
		}
	}

	// 添加Psr4空间
	private static function addPsr4($prefix, $paths, $prepend = false)
	{
		if (!$prefix) {
			// Register directories for the root namespace.
			if ($prepend) {
				self::$fallbackDirsPsr4 = array_merge(
					(array) $paths,
					self::$fallbackDirsPsr4
				);
			} else {
				self::$fallbackDirsPsr4 = array_merge(
					self::$fallbackDirsPsr4,
					(array) $paths
				);
			}
		} elseif (!isset(self::$prefixDirsPsr4[$prefix])) {
			// Register directories for a new namespace.
			$length = strlen($prefix);
			if ('\\' !== $prefix[$length - 1]) {
				throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
			}

			self::$prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
			self::$prefixDirsPsr4[$prefix]                = (array) $paths;
		} elseif ($prepend) {
			// Prepend directories for an already registered namespace.
			self::$prefixDirsPsr4[$prefix] = array_merge(
				(array) $paths,
				self::$prefixDirsPsr4[$prefix]
			);
		} else {
			// Append directories for an already registered namespace.
			self::$prefixDirsPsr4[$prefix] = array_merge(
				self::$prefixDirsPsr4[$prefix],
				(array) $paths
			);
		}
	}

	// 注册classmap
	public static function addClassMap($class, $map = '')
	{
		if (is_array($class)) {
			self::$classMap = array_merge(self::$classMap, $class);
		} else {
			self::$classMap[$class] = $map;
		}
	}


}



?>